package top.longmarch.flow.api;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import top.longmarch.flow.dto.LiteFlowDTO;
import top.longmarch.flow.dto.SyncComponentDTO;
import top.longmarch.flow.entity.LiteflowApp;
import top.longmarch.flow.entity.LiteflowBusinessCmp;
import top.longmarch.flow.entity.LiteflowChain;
import top.longmarch.flow.entity.LiteflowTemplateCmp;
import top.longmarch.flow.service.ILiteflowAppService;
import top.longmarch.flow.service.ILiteflowBusinessCmpService;
import top.longmarch.flow.service.ILiteflowTemplateCmpService;
import top.longmarch.flow.slot.LiteflowChainContext;
import top.longmarch.flow.utils.Result;
import top.longmarch.parser.node.ELBusPlus;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Api(tags = "流程引擎")
@RestController
@RequestMapping("/flow")
public class LogicFlowApi {

    @Resource
    private FlowExecutor flowExecutor;
    @Resource
    private ILiteflowBusinessCmpService liteflowBusinessCmpService;
    @Resource
    private ILiteflowTemplateCmpService liteflowTemplateCmpService;
    @Resource
    private ILiteflowAppService liteflowAppService;

    @ApiOperation(value = "获取应用列表")
    @GetMapping("/appList")
    public Result<List<LiteflowApp>> appList() {
        return Result.ok(liteflowAppService.list());
    }

    @ApiOperation(value = "logicFlow转化el表达式", notes = "输入logicFlow结构json字符串")
    @PostMapping("/jsonToEl")
    public Result<String> jsonToEl(@RequestBody LiteFlowDTO dto) {
        return Result.ok(ELBusPlus.toEl(dto.getJsonData(), dto.isTestPrint(), dto.isFormat()));
    }

    @ApiOperation(value = "同步业务组件")
    @PostMapping("/syncComponent")
    public Result<Object> syncComponent(@RequestBody SyncComponentDTO dto) {
        if ("temp".equals(dto.getCmpType())) {
            return Result.ok(liteflowTemplateCmpService.syncCmp(dto));
        }
        return Result.ok(liteflowBusinessCmpService.syncCmp(dto));
    }

    @ApiOperation(value = "获取模板组件列表")
    @GetMapping("/componentTempList")
    public Result<List<LiteflowTemplateCmp>> componentTempList() {
        return Result.ok(liteflowTemplateCmpService.list());
    }

    @ApiOperation(value = "获取业务组件列表")
    @PostMapping("/componentList")
    public Result<List<LiteflowBusinessCmp>> getComponentList(@RequestBody Map<String, Object> params) {
        String name = MapUtil.getStr(params, "name");
        LambdaQueryWrapper<LiteflowBusinessCmp> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(StrUtil.isNotBlank(name), LiteflowBusinessCmp::getLfClassQualifiedName, name);
        return Result.ok(liteflowBusinessCmpService.list(wrapper));
    }

    @ApiOperation(value = "获取流程列表")
    @GetMapping("/chainList")
    public Result<List<LiteflowChain>> chainList() {
        LiteflowResponse response = flowExecutor.execute2Resp("FlowChainList", null, LiteflowChainContext.class);
        LiteflowChainContext context = response.getContextBean(LiteflowChainContext.class);
        return Result.ok(context.getLiteflowChainList());
    }

    @ApiOperation(value = "查看流程详情")
    @GetMapping("/detail/{id}")
    public Result<LiteflowChain> show(@PathVariable("id") Long id) {
        LiteflowResponse response = flowExecutor.execute2Resp("FlowChainDetail", MapUtil.of("id", id), LiteflowChainContext.class);
        LiteflowChainContext context = response.getContextBean(LiteflowChainContext.class);
        return Result.ok(context.getLiteflowChain());
    }

    @ApiOperation(value = "保存设计好的流程图", notes = "输入logicFlow结构json字符串")
    @PostMapping("/saveJsonToElData")
    public Result<Object> saveJsonToElData(@RequestBody LiteFlowDTO dto) {
        LiteflowResponse response = flowExecutor.execute2Resp("SaveFlowChain", dto, LiteflowChainContext.class);
        LiteflowChainContext context = response.getContextBean(LiteflowChainContext.class);
        if (response.isSuccess()) {
            return Result.ok(context.getLiteflowChain());
        } else {
            return Result.fail(response.getMessage());
        }
    }

}
